package com.atguigu.gmall.item.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.item.service.ItemService;
import com.atguigu.gmall.list.client.ListFeignClient;
import com.atguigu.gmall.model.product.*;
import com.atguigu.gmall.product.client.ProductFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * @author atguigu-mqx
 */
@Service
public class ItemServiceImpl implements ItemService {

    @Autowired
    private ProductFeignClient prodcutFeignClient;

    //  获取一个线程池！
    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;

    @Autowired
    private ListFeignClient listFeignClient;

    @Override
    public Map<String, Object> getItem(Long skuId) {
        //  声明一个map 集合
        Map<String, Object> map = new HashMap<>();
        //  使用多线程的异步编排
        CompletableFuture<SkuInfo> skuInfoCompletableFuture = CompletableFuture.supplyAsync(() -> {
            //  获取skuInfo + skuImage
            SkuInfo skuInfo = prodcutFeignClient.getSkuInfo(skuId);
            //  需要将map 中添加数据，这个map 中的key 就是页面渲染的key
            map.put("skuInfo",skuInfo);
            return skuInfo;
        }, threadPoolExecutor);

        //  获取分类数据
        CompletableFuture<Void> categoryViewCompletableFuture = skuInfoCompletableFuture.thenAcceptAsync(skuInfo -> {
            BaseCategoryView categoryView = prodcutFeignClient.getCategoryView(skuInfo.getCategory3Id());
            map.put("categoryView", categoryView);
        }, threadPoolExecutor);

        //  获取回显并锁定数据
        CompletableFuture<Void> spuSaleAttrListCompletableFuture = skuInfoCompletableFuture.thenAcceptAsync(skuInfo -> {
            List<SpuSaleAttr> spuSaleAttrListCheckBySku = prodcutFeignClient.getSpuSaleAttrListCheckBySku(skuId, skuInfo.getSpuId());
            map.put("spuSaleAttrList", spuSaleAttrListCheckBySku);
        }, threadPoolExecutor);

        //  点击切换属性获取sku
        CompletableFuture<Void> mapJsonCompletableFuture = skuInfoCompletableFuture.thenAcceptAsync(skuInfo -> {
            Map idsMap = prodcutFeignClient.getSkuValueIdsMap(skuInfo.getSpuId());
            //  需要将它转换为Json
            String mapJson = JSON.toJSONString(idsMap);
            map.put("valuesSkuJson", mapJson);
        }, threadPoolExecutor);

        //  获取海报信息
        CompletableFuture<Void> spuPosterListCompletableFuture = skuInfoCompletableFuture.thenAcceptAsync(skuInfo -> {
            List<SpuPoster> spuPosterList = prodcutFeignClient.getSpuPosterBySpuId(skuInfo.getSpuId());
            map.put("spuPosterList", spuPosterList);
        }, threadPoolExecutor);

        //  获取价格：
        CompletableFuture<Void> skuPriceCompletableFuture = CompletableFuture.runAsync(() -> {
            BigDecimal skuPrice = prodcutFeignClient.getSkuPrice(skuId);
            map.put("price", skuPrice);
        }, threadPoolExecutor);

        //  获取商品的规格参数：
        CompletableFuture<Void> attrCompletableFuture = CompletableFuture.runAsync(() -> {
            List<BaseAttrInfo> attrList = prodcutFeignClient.getAttrList(skuId);

            List<Map<String, String>> list = attrList.stream().map(baseAttrInfo -> {
                //  声明一个map 集合
                Map<String, String> attrMap = new HashMap<>();
                String attrName = baseAttrInfo.getAttrName();
                String valueName = baseAttrInfo.getAttrValueList().get(0).getValueName();

                attrMap.put("attrName", attrName);
                attrMap.put("attrValue", valueName);
                return attrMap;
            }).collect(Collectors.toList());
            //  真正的数据：这个集合中只有两个数据！
            map.put("skuAttrList", list);
        }, threadPoolExecutor);

        //  远程调用热度排名数据接口！
        CompletableFuture<Void> incrCompletableFuture = CompletableFuture.runAsync(() -> {
            //  调用热度排名
            listFeignClient.incrHotScore(skuId);
        },threadPoolExecutor);

        //  所有的异步编排都完成了！
        CompletableFuture.allOf(
                skuInfoCompletableFuture,
                categoryViewCompletableFuture,
                spuSaleAttrListCompletableFuture,
                mapJsonCompletableFuture,
                spuPosterListCompletableFuture,
                skuPriceCompletableFuture,
                attrCompletableFuture,
                incrCompletableFuture
        ).join();
        return map;
    }
}
